package edu.whu.notepal.utils;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import edu.whu.notepal.common.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 陈磊
 */

@Component
@Slf4j
public class RedisClient {

    @Resource
    StringRedisTemplate stringRedisTemplate;

    /**
     * 用list存储全部数据
     */
    public <R> void saveList(String key, List<R> list, Long expiredTime, TimeUnit timeUnit){
        List<String> stringList =
                list.stream()
                        .map(i -> JSON.toJSONString(i))
                        .collect(Collectors.toList());
        if(stringList==null||stringList.size()==0){
            return;
        }
        stringRedisTemplate.opsForList().leftPushAll(key,stringList);
        stringRedisTemplate.expire(key,expiredTime,timeUnit);
    }

    /**
     * 获取Redis缓存的List数据
     * @param key
     * @param startIndex
     * @param endIndex
     * @param type
     * @param <R>
     * @return
     */
    public <R> List<R> getList(String key,int startIndex,int endIndex,Class<R> type){
        List<String> range = stringRedisTemplate.opsForList().range(key, startIndex, endIndex);
        List<R> list =
                range.stream()
                        .map(i -> JSON.parseObject(i, type))
                        .collect(Collectors.toList());
        return list;
    }

    public <R,ID> R queryWithPassThrough(String prefix,ID id,Class<R>type,Function<ID,R>function,Long expiredTime, TimeUnit timeUnit){
        String key = prefix+id;
        String json = stringRedisTemplate.opsForValue().get(key);
        if(StrUtil.isNotEmpty(json)){
            return JSON.parseObject(json,type);
        }
        //缓存击穿
        if(json!=null){
            throw new CustomException("id不存在");
        }
        R r = function.apply(id);
        //缓存空值
        if(r == null){
            stringRedisTemplate.opsForValue().set(key,"",expiredTime,timeUnit);
            throw new CustomException("id不存在");
        }
        stringRedisTemplate.opsForValue().set(key,JSON.toJSONString(r),expiredTime,timeUnit);
        return r;
    }

    public Boolean hasKey(Object...keys){
        String key = StrUtil.join("", keys);
        return stringRedisTemplate.hasKey(key);
    }

    public void deleteKey(Object...keys){
        String key = StrUtil.join("", keys);
        stringRedisTemplate.delete(key);
    }

}
